using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

namespace sforceExplorer
{
	/// <summary>
	/// Summary description for DataGridHyperLinkColumn.
	/// </summary>
	public class DataGridHyperLinkColumn : 
		DataGridTextBoxColumn
	{
		int _offSet = 0;

		bool attachedToEvent = false;
		string _linkLabelText = string.Empty;
		string _label = string.Empty;
		bool _useItalics = false;

		public delegate void LinkLabelColumnClickDelegate(object sender, LinkLabelColumnEventArgs e);
		public event LinkLabelColumnClickDelegate LinkLabelColumnClick;

		/// <summary>
		/// Creates a new instance of the ExtendedDataGridLinkLabelColumn class.
		/// </summary>
		public DataGridHyperLinkColumn():base()
		{
			MenuItem menu1 = new MenuItem("&Show in Browser");
			MenuItem menu2 = new MenuItem("&Copy ID");
			menu1.Click+=new EventHandler(menu1_Click);
			menu2.Click+=new EventHandler(menu2_Click);
			base.TextBox.ContextMenu = new ContextMenu(new MenuItem[] {menu1, menu2});
		}

		public bool UseItalics 
		{
			set { _useItalics = value; }
		}
		/// <summary>
		/// Gets or sets the caption of the label.If empty, the value of the underlying item will be showed.
		/// </summary>
		[DefaultValue("")]
		[Description("The caption of the label. If empty, the value of the underlying item will be showed.")]
		public string LinkLabelText
		{
			get
			{
				return _linkLabelText;
			}
			set
			{
				_linkLabelText = value;
			}
		}

		/// <summary>
		/// Gets or sets the top offset of the text.
		/// </summary>
		[System.ComponentModel.DefaultValue(0)]
		public int OffSet
		{
			get
			{
				return _offSet;
			}
			set
			{
				_offSet = value;
			}
		}

		protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
		{
			if(!attachedToEvent)
			{
				attachedToEvent = true;
				this.DataGridTableStyle.DataGrid.MouseMove +=new MouseEventHandler(DataGrid_MouseMove);
				this.DataGridTableStyle.DataGrid.MouseUp += new MouseEventHandler(DataGrid_MouseUp);
				this.TextBox.MouseUp +=new MouseEventHandler(DataGrid_MouseUp);
			}

			Font font = null;
			if (_useItalics)
				font = new Font(this.TextBox.Font.FontFamily, this.TextBox.Font.Size, FontStyle.Underline | FontStyle.Italic);
			else
				font = new Font(this.TextBox.Font.FontFamily, this.TextBox.Font.Size, FontStyle.Underline);
			//font.Italic = _useItalics;
			Brush brush = new SolidBrush(Color.Blue);
			g.FillRectangle(backBrush, bounds);
			this._label = this.GetColumnValueAtRow(source, rowNum).ToString();
			ToolTip tt = ((frmMain)this.DataGridTableStyle.DataGrid.FindForm()).toolTip1;
			tt.SetToolTip(this.DataGridTableStyle.DataGrid, "Click to view salesforce.com details, " + System.Environment.NewLine + "Right click to copy Id value to clipboard.");
			if(this.LinkLabelText == string.Empty)
				g.DrawString(this.GetColumnValueAtRow(source, rowNum).ToString(), font, brush, bounds.X, bounds.Y + this.OffSet);
			else
				g.DrawString(this.LinkLabelText, font, brush, bounds.X, bounds.Y + this.OffSet);

		}

		protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
		{
			base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
		}

		private void DataGrid_MouseMove(object sender, MouseEventArgs e)
		{
			try 
			{
				// X & Y are in the grid' coordinates. If they are in screen coordinates, call dataGrid1.PointToClient method 
				System.Drawing.Point pt = new Point(e.X, e.Y); 
 
				DataGrid.HitTestInfo hti = this.DataGridTableStyle.DataGrid.HitTest(pt); 
			
				ToolTip tt = ((frmMain)this.DataGridTableStyle.DataGrid.FindForm()).toolTip1;
				if(hti.Type == DataGrid.HitTestType.Cell) 
				{ 
					System.Type currColType = this.DataGridTableStyle.GridColumnStyles[hti.Column].GetType();
					if (currColType == this.GetType()) 
					{
						tt.Active = true;
						this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Hand;
					} 
					else 
					{ 
						this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
						tt.Active = false;
					}
					//				System.Diagnostics.Trace.WriteLine(this.DataGridTableStyle.GridColumnStyles[hti.Column].GetType().ToString());
					//				int rowNum = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
					//					System.Diagnostics.Trace.WriteLine("rowNum = " + rowNum.ToString() + ", hti.Column = " + hti.Column.ToString());
					//				if(rowNum == hti.Column)
					//				{
					//					tt.Active = true;
					//					this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Hand;
					//				}
					//				else
					//				{
					//					System.Diagnostics.Trace.WriteLine("rowNum = " + rowNum.ToString() + ", hti.Column = " + hti.Column.ToString());
					//					this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
					//					tt.Active = false;
					//				}
				} 
				else
				{
					this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
					tt.Active = false;
				}
			} 
			catch {}
		}

		private void DoLeftButtonClick(LinkLabelColumnEventArgs e) 
		{
			if(this.LinkLabelColumnClick != null)
				this.LinkLabelColumnClick(this, e);
			
		}

		private void DoRightButtonClick(LinkLabelColumnEventArgs e) 
		{
			this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
			this.TextBox.ContextMenu.Show(this.DataGridTableStyle.DataGrid, new Point(e.X, e.Y));
		}

		private void DataGrid_MouseUp(object sender, MouseEventArgs e)
		{
			try 
			{
				// X & Y are in the grid' coordinates. If they are in screen coordinates, call dataGrid1.PointToClient method 
				System.Drawing.Point pt = new Point(e.X, e.Y); 
 
				DataGrid.HitTestInfo hti = this.DataGridTableStyle.DataGrid.HitTest(pt); 
				
				if (hti.Row == -1) return;
				this.DataGridTableStyle.DataGrid.CurrentRowIndex = hti.Row;

				if(hti.Type == DataGrid.HitTestType.Cell) 
				{ 
					int rowNum = this.DataGridTableStyle.GridColumnStyles.IndexOf(this);
					if(rowNum == hti.Column)
					{
						BindingManagerBase bm = 
							this.DataGridTableStyle.DataGrid.BindingContext[this.DataGridTableStyle.DataGrid.DataSource, 
							this.DataGridTableStyle.DataGrid.DataMember]; 
							
						LinkLabelColumnEventArgs clickArgs = 
							new LinkLabelColumnEventArgs(bm.Current, this.MappingName, e.X, e.Y);

						this.TextBox.Tag = clickArgs;

						if (e.Button != MouseButtons.Right) 
						{
							this.DoLeftButtonClick(clickArgs);
							//						if(this.LinkLabelColumnClick != null)
							//							this.LinkLabelColumnClick(this, clickArgs);
						}
						else 
						{
							if (hti.Row == this.DataGridTableStyle.DataGrid.CurrentCell.RowNumber)
								this.DoRightButtonClick(clickArgs);
							//						this.DataGridTableStyle.DataGrid.Parent.Cursor = Cursors.Default;
							//						this.TextBox.Tag = clickArgs;
							//						this.TextBox.ContextMenu.Show(this.DataGridTableStyle.DataGrid, new Point(e.X, e.Y));
						}
					}
				}
			} 
			catch (Exception ex) 
			{
				System.Diagnostics.Trace.WriteLine("Mouse Up Error: " + ex.Message);
			}
		}

		private void menu1_Click(object sender, EventArgs e)
		{
			DoLeftButtonClick((LinkLabelColumnEventArgs)this.TextBox.Tag);
		}

		private void menu2_Click(object sender, EventArgs e)
		{
			Clipboard.SetDataObject(((LinkLabelColumnEventArgs)this.TextBox.Tag).Id);
		}
	}

	/// <summary>
	/// EventArgs used by the ExtendedDataGridLinkLabelColumn class.
	/// </summary>
	public class LinkLabelColumnEventArgs: EventArgs
	{
		object rowValue;
		string labelText;
		string id;
		int x;
		int y;
		/// <summary>
		/// Creates a new instance of the LinkLabelColumnEventArgs class.
		/// </summary>
		/// <param name="rowValue">The value of the underlying row.</param>
		public LinkLabelColumnEventArgs(object rowValue, string columnName, int X, int Y):base()
		{
			this.rowValue = rowValue;
			this.labelText = labelText;
			this.id = ((System.Data.DataRowView)rowValue).Row[columnName].ToString();
			this.x = X;
			this.y = Y;
		}

		public int X { get { return x; } set { x = value; } }
		public int Y { get { return y; } set { y = value; } }

		public string Id 
		{
			get 
			{
				return id;
			}
			set { id = value; }
		}
		public string LabelText 
		{
			get { return labelText; }
			set { labelText = value; }
		}
		/// <summary>
		/// Gets or sets the value of the underlying row.
		/// </summary>
		public object RowValue
		{
			get
			{
				return rowValue;
			}
			set
			{
				rowValue = value;
			}
		}
	}
}
